#ifndef __DRIVER_CDROM_H
#define __DRIVER_CDROM_H

#define DRIVER_NAME "iso9660-cdrom"
#define DRIVER_VER "0.1"

#define DEVICE_NAME "cdrom"

//define channel
#define ATA_PRIMARY_CHANNEL 0x0
#define ATA_SLAVE_CHANNEL 0x01

//define device type
#define ATA_DEVICE 0x00
#define ATAPI_DEVICE 0x01

//define device sel
#define ATA_MASTER_DEVICE 0x00
#define ATA_SLAVE_DEVICE 0x01

//ide opeartor
#define IDE_READ 0
#define IDE_WRITE 1

//device register mask bits
#define DEV_MBS 0xA0 //bits 7 and 5 are set to 1

//make ATA device register mask
#define ATA_DEVICE_MASK(mode, sel, head) ((DEV_MBS) | (sel) << 4 | (head)&0x07)

//define ata device command and  register io address
#define ATA_PRIMARY_CMDREG_BA 0x1f0
#define ATA_PRIMARY_ALTREG_BA 0x3f6
#define ATA_SLAVE_CMDREG_BA 0x170
#define ATA_SLAVE_ALTREG_BA 0x376
#define ATA_DMA_BA 0x0

//define ata command reg group
//ata data reg
#define ATA_REG_DATA 0x00
//ata error reg
#define ATA_REG_ERR 0x01
//ata feature reg
#define ATA_REG_FEATURE 0x01
//ata sector count0 reg
#define ATA_REG_SECCNT0 0x02
//ata group lba address0 reg
#define ATA_REG_LBA0 0x03
//ata lba address1 reg
#define ATA_REG_LBA1 0x04
//ata lba address2 reg
#define ATA_REG_LBA2 0x05
//ata sel reg
#define ATA_REG_HDDSEL 0x06
//ata command regm
#define ATA_REG_CMD 0x07
//ata status reg
#define ATA_REG_STATUS 0x07
//ata sector count1 reg
#define ATA_REG_SECCNT1 0x08
//ata lba3 address reg
#define ATA_REG_LBA3 0x09
//ata lba4 address reg
#define ATA_REG_LBA4 0x0A
//ata lba5 address reg
#define ATA_REG_LBA5 0x0B

//ata alternate status reg
#define ATA_REG_ALTSTU 0x0C
//ata control group control reg
#define ATA_REG_CTRL 0x0C

//ata control device address reg,unuse
#define ATA_REG_DRVAD_REG 0x0D
//ata bus ide dma0
#define ATA_REG_BUSIDEDMA0_REG 0x0E
//ata bus ide dma1
#define ATA_REG_BUSIDEDMA1_REG 0x0F
//ata bus ide dma2
#define ATA_REG_BUSIDEDMA2_REG 0x10
//ata bus ide dma3
#define ATA_REG_BUSIDEDMA3_REG 0x11
//ata bus ide dma4
#define ATA_REG_BUSIDEDMA4_REG 0x12
//ata bus ide dma5
#define ATA_REG_BUSIDEDMA5_REG 0x13
//ata bus ide dma6
#define ATA_REG_BUSIDEDMA6_REG 0x14
//ata bus ide dma7
#define ATA_REG_BUSIDEDMA7_REG 0x15

//define ata status
//Busy
#define ATA_STATUS_BUSY 0x80
//Drive ready
#define ATA_STATUS_READY 0x40
//Drive write fault
#define ATA_STATUS_DEVFAULT 0x20
//Drive seek complete
#define ATA_STATUS_DSC 0x10
//Data request ready
#define ATA_STATUS_DRQ 0x08
//Corrected data
#define ATA_STATUS_CORR 0x04
//Index
#define ATA_STATUS_IDX 0x02
//Error
#define ATA_STATUS_ERR 0x01

//define error reg filed
// Bad block
#define ATA_ER_BBK 0x80
//Uncorrectable data
#define ATA_ER_UNC 0x40
//Media changed
#define ATA_ER_MC 0x20
//ID mark not found
#define ATA_ER_IDNF 0x10
//Media change request
#define ATA_ER_MCR 0x08
//Command aborted
#define ATA_ER_ABRT 0x04
//Track 0 not found
#define ATA_ER_TK0NF 0x02
//No address mark
#define ATA_ER_AMNF 0x01

//define command
//When you write to the Command/Status port, you are executing one of the commands below
//ATA command
#define ATA_CMD_DRIVERCHECK 0x90
#define ATA_CMD_SECTORCHECK 0x40
#define ATA_CMD_READ_PIO 0x20
#define ATA_CMD_READ_PIO_EXT 0x24
#define ATA_CMD_READ_DMA 0xC8
#define ATA_CMD_READ_DMA_EXT 0x25
#define ATA_CMD_WRITE_PIO 0x30
#define ATA_CMD_WRITE_PIO_EXT 0x34
#define ATA_CMD_WRITE_DMA 0xCA
#define ATA_CMD_WRITE_DMA_EXT 0x35
#define ATA_CMD_CACHE_FLUSH 0xE7
#define ATA_CMD_CACHE_FLUSH_EXT 0xEA
#define ATA_CMD_PACKET 0xA0
#define ATA_CMD_IDENTIFY_PACKET 0xA1
#define ATA_CMD_IDENTIFY 0xEC
//ATAPI command
#define ATAPI_CMD_EJECT 0x1B
#define ATAPI_CMD_READ 0xA8

//ATAPI sector size
#define ATAPI_SECTOR_SIZE 2048

//device control
#define ATA_CONTROL_IEN 0x1
#define ATA_CONTROL_SRST 0x2

#define IDE_DISK_NUM (PAGE_HIGH_BASE + 0x0475)

typedef struct ide_info
{
    uint16_t general_config;                       //general config
    uint16_t obsolete0;                            //obsolete
    uint16_t specific_config;                      //specific cnfig
    uint16_t obsolete1;                            //obsolete
    uint16_t retired0[2];                          //retired
    uint16_t compactFlash[2];                      //reserved for compactFlash association
    uint16_t retired1;                             //retired
    uint16_t serial_number[10];                    //serial number (20 ASCII characters)
    uint16_t retired2[2];                          //retired
    uint16_t obsolete3;                            //obsolete
    uint16_t firmware_version[4];                  //firmware revision(8 ASICC characters)
    uint16_t model_number[20];                     //model number(40 ASCII characters
    uint16_t max_logical_transfer_per_DRQ;         //maximum number of logical sectors that shall be trasferred per DRQ data block
    uint16_t trusted_computing_feature_set_option; //trusted computing feature feature set option
    uint16_t compabilities0;                       //capabilities
    uint16_t compabilities1;                       //capabilities
    uint16_t obsolete4[2];                         //obsolete
    //15:8 free-fall control sensitivity
    //7:3  reserved
    //2    report in word 88 are valid
    //1    report in word 70:64 are valid
    uint16_t report_88_70to64_valid;
    uint16_t obsolete5[5]; //obsolete
    //15:9 reserved
    //8 multiple sector setting is valid
    //7:0   current setting for number of logical sectors that shall be transferred per DRQ data block on READ/WRITE Multiple commands
    uint16_t mul_sec_setting_valid;
    uint16_t lba28_sectors[2]; //total number of logical sectors for 28bits CMD
    uint16_t obsolete6;        //obsolete
    //15:11 reserved
    //10:8 multiword DMA mode 210 is selected
    //7:3  reserved
    //2:0   multiword DMA mode 210 and below are support
    uint16_t multword_dma_select;
    //15:8 reserved
    //7:0   PIO mode support
    uint16_t PIO_mode_supported;
    uint16_t min_mulword_dma_cycle_time_per_word;          //minimum multiword DMA transfer cycle time per word
    uint16_t manufacture_recommend_mulword_DMA_cycle_time; //manufacturer's recommend multiword DMA transfer cycle time
    uint16_t min_PIO_cycle_time_flow_control;              //minimum PIO transfer cycle time without flow control
    uint16_t min_PIO_cycle_time_IOREADY_flow_contorl;      //minimum PIO transfer cycle time with flow control
    uint16_t reserved1[2];                                 //reserved
    uint16_t reserved2[4];                                 //reserved for the IDENTIFY PACKET DEVICE command
    uint16_t queue_depth;                                  //queue depth
    uint16_t SATA_capabilities;                            //serial ATA capabilities
    uint16_t reserved3;                                    //served for serial ATA
    uint16_t SATA_features_support;                        //serial ATA features support
    uint16_t SATA_features_enable;                         //serial ATA features enable
    uint16_t major_version;                                //major version number
    uint16_t minor_version;                                //minjor version number
    uint16_t cmd_set0;                                     //command and feature sets supported
    uint16_t cmd_set1;                                     //command and feature sets supported
    uint16_t cmd_feature_sets_supported2;                  //command and feature sets supported
    uint16_t cmd_feature_sets_supported3;                  //command and feature sets supported or enable
    uint16_t cmd_feature_sets_supported4;                  //command and feature sets supported or enable
    uint16_t cmd_feature_sets_supported5;                  //command and feature sets supportedd or enable
    //15 reserved
    //14:8 ultra DMA mode is slected
    //7 reserved
    //6:0   ultra DMA mode and below are supported
    uint16_t ultra_DMA_mode;
    uint16_t time_required_erase_cmd;    //time required for Normal Erase mode SECURITY ERASE UNIT command
    uint16_t time_required_enhanced_cmd; //time required for Enhandced Erase mode SECURity_ERASE UNIT command
    uint16_t current_APM_level_value;    //current APM level value
    uint16_t master_password_identifier; //master password identifier
    uint16_t hardware_reset_result;      //hardware reset result
    //current AAM value
    // 15:8 vendor's recommanded AAM value
    // 7:8 current AAM value
    uint16_t current_AAM_value;
    //stream mininum request size
    uint16_t stream_min_request_size;
    //stream transger Fime-DMA
    uint16_t streaming_transger_time_DMA;
    //straming access letency-DMA_PIO
    uint16_t streaming_access_latency_DMA_PIO;
    //streaming performance granularity
    uint16_t streaming_performance_granularity[2];
    //total number of logical sectors for 48-bits command
    uint16_t lba48_sectors[4];
    //streaming transger Time-PIO
    uint16_t streaming_transfer_time_PIO;
    //reserved
    uint16_t reserved4;
    //physicia sector size/logical sector size
    uint16_t physical_logical_sector_size;
    //inter-seek delay for ISO-7779 acoustic testing in microsenconds
    uint16_t inter_seek_delay;
    //world wide name
    uint16_t world_wide_name[4];
    //reserved
    uint16_t reserved5[4];
    //reserved for TLC
    uint16_t reserved6;
    //logical sector size
    uint16_t words_per_logical_sector[2];
    //commands and feacture sets supported
    uint16_t cmd_feature_supported;
    //command and feacture sets supported or enable
    uint16_t cmd_feature_supported_enable;
    //reserved for expanded support and enable setting
    uint16_t reserved7[6];
    //obsolete
    uint16_t obsolete7;
    //security status
    uint16_t security_status;
    //vendor specific
    uint16_t vendor_specific[31];
    //CFA power mode
    uint16_t CFA_power_mode;
    //reserved for the compatFlash association
    uint16_t reserved8[7];
    //device nominal form factor
    uint16_t dev_for_factor;
    //reserved
    uint16_t reserved9[7];
    //current media serial number(ARA string)
    uint16_t current_media_serial_number[30];
    //SCT command transport
    uint16_t SCT_cmd_transport;
    //reserved for CE-ATA
    uint16_t reserved10[2];
    //alignment of logical block within pysical block
    uint16_t alignment_logical_block_within_pysical_block;
    //write-read-verity sector count mode 3
    uint16_t write_read_verity_sector_count_mode3;
    //write_read_verity_sector_count_mode 2
    uint16_t write_read_verity_sector_count_mode2;
} ide_info_t;

typedef struct device_extension device_extension_t;

//define channel info
typedef struct ide_channel
{
    uint16_t iobase;     //io base
    uint16_t ctrlbase;   //control base
    uint16_t bmasteride; //bus master ide
    uint8_t irqno;       //irq number
    uint8_t curop;       //current operator
    uint8_t curactive;   //active in master or slave
    device_extension_t *extension;
} ide_channel_t;

typedef struct device_extension
{
    device_object_t *device_object;
    char device_name[DEVICE_NAME_LEN+1];
    ide_channel_t *channel;
    int driver;
    ide_info_t *info;
    uint32_t command_sets;
    uint32_t type;
    uint16_t capabilities;
    uint16_t signature;
    uint32_t size;
    uint32_t rwoff;
    uint8_t bootable; //can boot from cdrom
    uint32_t exist;   //device exist
} device_extension_t;

extern ide_channel_t channelinfo[2];

#endif